home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d902.lha / Less / Source / source.lha / screen.c < prev    next >
C/C++ Source or Header  |  1993-02-18  |  20KB  |  811 lines

  1. /*
  2.  * Routines which deal with the characteristics of the terminal.
  3.  * Uses termcap to be as terminal-independent as possible.
  4.  *
  5.  * {{ Someday this should be rewritten to use curses. }}
  6.  */
  7.  
  8. #include "less.h"
  9.  
  10. #if XENIX
  11. #include <sys/types.h>
  12. #include <sys/ioctl.h>
  13. #endif
  14.  
  15. #ifdef AMIGA
  16. extern int sc_window_spec;   /* user's requested -z */
  17. extern int scroll; /* half-page scroll length */
  18. extern int nrow, ncol;
  19. #else
  20. #if TERMIO
  21. #include <termio.h>
  22. #else
  23. #include <sgtty.h>
  24. #endif
  25. #endif
  26.  
  27. #ifdef TIOCGWINSZ
  28. #include <sys/ioctl.h>
  29. #else
  30. /*
  31.  * For the Unix PC (ATT 7300 & 3B1):
  32.  * Since WIOCGETD is defined in sys/window.h, we can't use that to decide
  33.  * whether to include sys/window.h.  Use SIGWIND from sys/signal.h instead.
  34.  */
  35. #include <signal.h>
  36. #ifdef SIGWIND
  37. #include <sys/window.h>
  38. #endif
  39. #endif
  40.  
  41.  
  42. /*
  43.  * Strings passed to tputs() to do various terminal functions.
  44.  */
  45. static char
  46.         *sc_pad,                /* Pad string */
  47.         *sc_home,               /* Cursor home */
  48.         *sc_addline,            /* Add line, scroll down following lines */
  49.         *sc_lower_left,         /* Cursor to last line, first column */
  50.         *sc_move,               /* General cursor positioning */
  51.         *sc_clear,              /* Clear screen */
  52.         *sc_eol_clear,          /* Clear to end of line */
  53.         *sc_s_in,               /* Enter standout (highlighted) mode */
  54.         *sc_s_out,              /* Exit standout mode */
  55.         *sc_u_in,               /* Enter underline mode */
  56.         *sc_u_out,              /* Exit underline mode */
  57.         *sc_b_in,               /* Enter bold mode */
  58.         *sc_b_out,              /* Exit bold mode */
  59. #ifdef AMIGA
  60.         *sc_it_in,              /* Enter italic mode */
  61.         *sc_it_out,             /* Exit italic mode */
  62.         *sc_nv_in,              /* Enter inverse video mode */
  63.         *sc_nv_out,             /* Exit inverse video mode */
  64. #endif
  65.         *sc_visual_bell,        /* Visual bell (flash screen) sequence */
  66.         *sc_backspace,          /* Backspace cursor */
  67.         *sc_init,               /* Startup terminal initialization */
  68.         *sc_deinit;             /* Exit terminal de-intialization */
  69. #ifdef DUMBTERM
  70. static int dumb;
  71. #endif
  72. static int hard;
  73.  
  74. public int auto_wrap;           /* Terminal does \r\n when write past margin */
  75. public int ignaw;               /* Terminal ignores \n immediately after wrap */
  76. public int erase_char, kill_char; /* The user's erase and line-kill chars */
  77. public int sc_width, sc_height; /* Height & width of screen */
  78. public int sc_window = -1;      /* window size for forward and backward */
  79. public int bo_width, be_width;  /* Printing width of boldface sequences */
  80. public int ul_width, ue_width;  /* Printing width of underline sequences */
  81. public int so_width, se_width;  /* Printing width of standout sequences */
  82. public int it_width, ie_width;  /* Printing width of italic sequences */
  83. public int nv_width, ne_width;  /* Printing width of inv video sequences */
  84.  
  85. /*
  86.  * These two variables are sometimes defined in,
  87.  * and needed by, the termcap library.
  88.  * It may be necessary on some systems to declare them extern here.
  89.  */
  90. /*extern*/ short ospeed;        /* Terminal output baud rate */
  91. /*extern*/ char PC;             /* Pad character */
  92.  
  93. extern int quiet;               /* If VERY_QUIET, use visual bell for bell */
  94. #ifdef DUMBTERM
  95. extern int know_dumb;           /* Don't complain about a dumb terminal */
  96. #endif
  97. extern int back_scroll;
  98. char *tgetstr();
  99. char *tgoto();
  100.  
  101. /*
  102.  * Change terminal to "raw mode", or restore to "normal" mode.
  103.  * "Raw mode" means
  104.  *      1. An outstanding read will complete on receipt of a single keystroke.
  105.  *      2. Input is not echoed.
  106.  *      3. On output, \n is mapped to \r\n.
  107.  *      4. \t is NOT expanded into spaces.
  108.  *      5. Signal-causing characters such as ctrl-C (interrupt),
  109.  *         etc. are NOT disabled.
  110.  * It doesn't matter whether an input \n is mapped to \r, or vice versa.
  111.  */
  112. #ifdef __STDC__
  113. void raw_mode (int on)
  114. #else
  115.         public void
  116. raw_mode(on)
  117.         int on;
  118. #endif
  119. {
  120. #ifdef AMIGA
  121.         extern int do_echo;
  122.  
  123.         if (on)
  124.                 do_echo = 0;
  125.         else
  126.                 do_echo = 1;
  127.         erase_char = 8; /* ^H */
  128.         kill_char = 24; /* ^X */
  129. #else
  130. #if TERMIO
  131.         struct termio s;
  132.         static struct termio save_term;
  133.  
  134.         if (on)
  135.         {
  136.                 /*
  137.                  * Get terminal modes.
  138.                  */
  139.                 ioctl(2, TCGETA, &s);
  140.  
  141.                 /*
  142.                  * Save modes and set certain variables dependent on modes.
  143.                  */
  144.                 save_term = s;
  145.                 ospeed = s.c_cflag & CBAUD;
  146.                 erase_char = s.c_cc[VERASE];
  147.                 kill_char = s.c_cc[VKILL];
  148.  
  149.                 /*
  150.                  * Set the modes to the way we want them.
  151.                  */
  152.                 s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
  153.                 s.c_oflag |=  (OPOST|ONLCR|TAB3);
  154.                 s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);
  155.                 s.c_cc[VMIN] = 1;
  156.                 s.c_cc[VTIME] = 0;
  157.         } else
  158.         {
  159.                 /*
  160.                  * Restore saved modes.
  161.                  */
  162.                 s = save_term;
  163.         }
  164.         ioctl(2, TCSETAW, &s);
  165. #else
  166.         struct sgttyb s;
  167.         static struct sgttyb save_term;
  168.  
  169.         if (on)
  170.         {
  171.                 /*
  172.                  * Get terminal modes.
  173.                  */
  174.                 ioctl(2, TIOCGETP, &s);
  175.  
  176.                 /*
  177.                  * Save modes and set certain variables dependent on modes.
  178.                  */
  179.                 save_term = s;
  180.                 ospeed = s.sg_ospeed;
  181.                 erase_char = s.sg_erase;
  182.                 kill_char = s.sg_kill;
  183.  
  184.                 /*
  185.                  * Set the modes to the way we want them.
  186.                  */
  187.                 s.sg_flags |= CBREAK;
  188.                 s.sg_flags &= ~(ECHO|XTABS);
  189.         } else
  190.         {
  191.                 /*
  192.                  * Restore saved modes.
  193.                  */
  194.                 s = save_term;
  195.         }
  196.         ioctl(2, TIOCSETN, &s);
  197. #endif
  198. #endif
  199. }
  200.  
  201. #ifdef DUMBTERM
  202.         static void
  203. cannot(s)
  204.         char *s;
  205. {
  206.         char message[100];
  207.  
  208.         if (know_dumb)
  209.                 /*
  210.                  * He knows he has a dumb terminal, so don't tell him.
  211.                  */
  212.                 return;
  213.  
  214.         sprintf(message, "WARNING: terminal cannot \"%s\"", s);
  215.         error(message);
  216. }
  217. #endif
  218.  
  219. #ifdef AMIGA
  220. /*
  221.  * Set forward and backward scrolling limits based upon user's requests
  222.  * and screen size
  223.  */
  224. #ifdef __STDC__
  225. void set_scroll (void)
  226. #else
  227.         public void
  228. set_scroll()
  229. #endif
  230. {
  231.         if (sc_window_spec > 0)
  232.             sc_window = (sc_window_spec < nrow? sc_window_spec: nrow - 1);
  233.         else
  234.             sc_window = nrow - 1;
  235. }
  236. #endif
  237.  
  238. /*
  239.  * Get terminal capabilities via termcap.
  240.  */
  241. #ifdef __STDC__
  242. void get_term (void)
  243. #else
  244.         public void
  245. get_term()
  246. #endif
  247. {
  248. #ifdef AMIGA
  249.         static char go_to_home[10];
  250.  
  251.         getrowcol(); /* find out window size */
  252.         scroll = nrow/2;
  253.         set_scroll();
  254.  
  255. /* I didn't want to port termcap for now, but there is a version
  256.  on fish #14 that someone might want to use */
  257.         sc_pad = "";                /* Pad string */
  258.         sc_home = "\x1b[\x31;1H";           /* Cursor home */
  259.         sc_addline = "\x1b[L";       /* Add line, scroll down following lines */
  260.         sprintf(go_to_home, "\x1b[%ld;1H", nrow);
  261.         sc_lower_left = go_to_home;     /* Cursor to last line, first column */
  262.         sc_move = "";               /* General cursor positioning */
  263.         sc_clear = "\x1b[H\x1b[J";  /* Clear screen */
  264.         sc_eol_clear = "\x1b[K";     /* Clear to end of line */
  265.         sc_s_in = "\x1b[\x37m";   /* Enter standout (highlighted) mode */
  266.         sc_s_out = "\x1b[\x30m";         /* Exit standout mode */
  267.         sc_u_in = "\x1b[\x34m";         /* Enter underline mode */
  268.         sc_u_out = "\x1b[\x30m";         /* Exit underline mode */
  269.         sc_b_in = "\x1b[\x31m";         /* Enter bold mode */
  270.         sc_b_out = "\x1b[\x30m";       /* Exit bold mode */
  271.         sc_it_in = "\x1b[\x33m";     /* Enter italic mode */
  272.         sc_it_out = "\x1b[\x30m";    /* Exit italic mode */
  273.         sc_nv_in = "\x1b[\x37m";     /* Enter inverse video mode */
  274.         sc_nv_out = "\x1b[\x30m";    /* Exit inverse video mode */
  275.         /* We define visual_bell to be null, because on the Amiga the
  276.            ordinary BELL signal (^G) does a visual bell.  Thus, in the
  277.            Amiga version of Less, the user's choice is between a visual
  278.            bell (not quiet) and no indicator at all (quiet)
  279.         */
  280.         sc_visual_bell = NULL;    /* Visual bell (flash screen) sequence */
  281.         sc_backspace = "\b";      /* Backspace cursor */
  282.         sc_init = "";               /* Startup terminal initialization */
  283.         sc_deinit = "";             /* Exit terminal de-intialization */
  284.         sc_height = nrow;
  285.         sc_width = ncol;
  286.  
  287.         so_width = 0;
  288.         it_width = ie_width = nv_width = ne_width =
  289.         be_width = bo_width = ue_width = ul_width = se_width = so_width;
  290.  
  291. #else
  292.         char termbuf[2048];
  293.         char *sp;
  294. #ifdef TIOCGWINSZ
  295.         struct winsize w;
  296. #else
  297. #ifdef WIOCGETD
  298.         struct uwdata w;
  299. #endif
  300. #endif
  301.         static char sbuf[1024];
  302.  
  303.         char *getenv();
  304.  
  305.         /*
  306.          * Find out what kind of terminal this is.
  307.          */
  308.         if (tgetent(termbuf, getenv("TERM")) <= 0)
  309.                 dumb = 1;
  310.  
  311.         /*
  312.          * Get size of the screen.
  313.          */
  314. #ifdef TIOCGWINSZ
  315.         if (ioctl(2, TIOCGWINSZ, &w) == 0 && w.ws_row)
  316.                 sc_height = w.ws_row;
  317.         else
  318. #else
  319. #ifdef WIOCGETD
  320.         if (ioctl(2, WIOCGETD, &w) == 0 && w.uw_height)
  321.                 sc_height = w.uw_height/w.uw_vs;
  322.         else
  323. #endif
  324. #endif
  325.                 sc_height = tgetnum("li");
  326.         if (dumb || sc_height < 0 || tgetflag("hc"))
  327.         {
  328.                 /* Oh no, this is a hardcopy terminal. */
  329.                 hard = 1;
  330.                 sc_height = 24;
  331.         }
  332.         /*
  333.          * This is terrible - the following if "knows" that it is being
  334.          * executed *after* command line and environment options have
  335.          * already been parsed.  Should it be executed in the main program
  336.          * instead?
  337.          */
  338.         if ((sc_window <= 0) || (sc_window >= sc_height))
  339.                 sc_window = sc_height-1;
  340.  
  341. #ifdef TIOCGWINSZ
  342.         if (ioctl(2, TIOCGWINSZ, &w) == 0 && w.ws_col)
  343.                 sc_width = w.ws_col;
  344.         else
  345. #ifdef WIOCGETD
  346.         if (ioctl(2, WIOCGETD, &w) == 0 && w.uw_width)
  347.                 sc_width = w.uw_width/w.uw_hs;
  348.         else
  349. #endif
  350. #endif
  351.                 sc_width = tgetnum("co");
  352.         if (dumb || sc_width < 0)
  353.                 sc_width = 80;
  354.  
  355.         auto_wrap = tgetflag("am");
  356.         ignaw = tgetflag("xn");
  357.  
  358.         /*
  359.          * Assumes termcap variable "sg" is the printing width of
  360.          * the standout sequence, the end standout sequence,
  361.          * the underline sequence, the end underline sequence,
  362.          * the boldface sequence, and the end boldface sequence.
  363.          */
  364.         if ((so_width = tgetnum("sg")) < 0)
  365.                 so_width = 0;
  366.         be_width = bo_width = ue_width = ul_width = se_width = so_width;
  367.  
  368.         /*
  369.          * Get various string-valued capabilities.
  370.          */
  371.         sp = sbuf;
  372.  
  373.         sc_pad = (dumb) ? NULL : tgetstr("pc", &sp);
  374.         if (sc_pad != NULL)
  375.                 PC = *sc_pad;
  376.  
  377.         sc_init = (dumb) ? NULL : tgetstr("ti", &sp);
  378.         if (sc_init == NULL)
  379.                 sc_init = "";
  380.  
  381.         sc_deinit= (dumb) ? NULL : tgetstr("te", &sp);
  382.         if (sc_deinit == NULL)
  383.                 sc_deinit = "";
  384.  
  385.         sc_eol_clear = (dumb) ? NULL : tgetstr("ce", &sp);
  386.         if (hard || sc_eol_clear == NULL || *sc_eol_clear == '\0')
  387.         {
  388.                 cannot("clear to end of line");
  389.                 sc_eol_clear = "";
  390.         }
  391.  
  392.         sc_clear = (dumb) ? NULL : tgetstr("cl", &sp);
  393.         if (hard || sc_clear == NULL || *sc_clear == '\0')
  394.         {
  395.                 cannot("clear screen");
  396.                 sc_clear = "\n\n";
  397.         }
  398.  
  399.         sc_move = (dumb) ? NULL : tgetstr("cm", &sp);
  400.         if (hard || sc_move == NULL || *sc_move == '\0')
  401.         {
  402.                 /*
  403.                  * This is not an error here, because we don't
  404.                  * always need sc_move.
  405.                  * We need it only if we don't have home or lower-left.
  406.                  */
  407.                 sc_move = "";
  408.         }
  409.  
  410.         sc_s_in = (dumb) ? NULL : tgetstr("so", &sp);
  411.         if (hard || sc_s_in == NULL)
  412.                 sc_s_in = "";
  413.  
  414.         sc_s_out = (dumb) ? NULL : tgetstr("se", &sp);
  415.         if (hard || sc_s_out == NULL)
  416.                 sc_s_out = "";
  417.  
  418.         sc_u_in = (dumb) ? NULL : tgetstr("us", &sp);
  419.         if (hard || sc_u_in == NULL)
  420.                 sc_u_in = sc_s_in;
  421.  
  422.         sc_u_out = (dumb) ? NULL : tgetstr("ue", &sp);
  423.         if (hard || sc_u_out == NULL)
  424.                 sc_u_out = sc_s_out;
  425.  
  426.         sc_b_in = (dumb) ? NULL : tgetstr("md", &sp);
  427.         if (hard || sc_b_in == NULL)
  428.         {
  429.                 sc_b_in = sc_s_in;
  430.                 sc_b_out = sc_s_out;
  431.         } else
  432.         {
  433.                 sc_b_out = (dumb) ? NULL : tgetstr("me", &sp);
  434.                 if (hard || sc_b_out == NULL)
  435.                         sc_b_out = "";
  436.         }
  437.  
  438.         sc_visual_bell = (dumb) ? NULL : tgetstr("vb", &sp);
  439.         if (hard || sc_visual_bell == NULL)
  440.                 sc_visual_bell = "";
  441.  
  442.         sc_home = (dumb) ? NULL : tgetstr("ho", &sp);
  443.         if (hard || sc_home == NULL || *sc_home == '\0')
  444.         {
  445.                 if (*sc_move == '\0')
  446.                 {
  447.                         cannot("home cursor");
  448.                         /*
  449.                          * This last resort for sc_home is supposed to
  450.                          * be an up-arrow suggesting moving to the
  451.                          * top of the "virtual screen". (The one in
  452.                          * your imagination as you try to use this on
  453.                          * a hard copy terminal.)
  454.                          */
  455.                         sc_home = "|\b^";
  456.                 } else
  457.                 {
  458.                         /*
  459.                          * No "home" string,
  460.                          * but we can use "move(0,0)".
  461.                          */
  462.                         strcpy(sp, tgoto(sc_move, 0, 0));
  463.                         sc_home = sp;
  464.                         sp += strlen(sp) + 1;
  465.                 }
  466.         }
  467.  
  468.         sc_lower_left = (dumb) ? NULL : tgetstr("ll", &sp);
  469.         if (hard || sc_lower_left == NULL || *sc_lower_left == '\0')
  470.         {
  471.                 if (*sc_move == '\0')
  472.                 {
  473.                         cannot("move cursor to lower left of screen");
  474.                         sc_lower_left = "\r";
  475.                 } else
  476.                 {
  477.                         /*
  478.                          * No "lower-left" string,
  479.                          * but we can use "move(0,last-line)".
  480.                          */
  481.                         strcpy(sp, tgoto(sc_move, 0, sc_height-1));
  482.                         sc_lower_left = sp;
  483.                         sp += strlen(sp) + 1;
  484.                 }
  485.         }
  486.  
  487.         /*
  488.          * To add a line at top of screen and scroll the display down,
  489.          * we use "al" (add line) or "sr" (scroll reverse).
  490.          */
  491.         if (dumb)
  492.                 sc_addline = NULL;
  493.         else if ((sc_addline = tgetstr("al", &sp)) == NULL ||
  494.                  *sc_addline == '\0')
  495.                 sc_addline = tgetstr("sr", &sp);
  496.  
  497.         if (hard || sc_addline == NULL || *sc_addline == '\0')
  498.         {
  499.                 cannot("scroll backwards");
  500.                 sc_addline = "";
  501.                 /* Force repaint on any backward movement */
  502.                 back_scroll = 0;
  503.         }
  504.  
  505.         if (dumb || tgetflag("bs"))
  506.                 sc_backspace = "\b";
  507.         else
  508.         {
  509.                 sc_backspace = tgetstr("bc", &sp);
  510.                 if (sc_backspace == NULL || *sc_backspace == '\0')
  511.                         sc_backspace = "\b";
  512.         }
  513. #endif
  514. }
  515.  
  516.  
  517. /*
  518.  * Below are the functions which perform all the
  519.  * terminal-specific screen manipulation.
  520.  */
  521.  
  522.  
  523. /*
  524.  * Initialize terminal
  525.  */
  526. #ifdef __STDC__
  527. void init (void)
  528. #else
  529.         public void
  530. init()
  531. #endif
  532. {
  533.         tputs(sc_init, sc_height, putchr);
  534. }
  535.  
  536. /*
  537.  * Deinitialize terminal
  538.  */
  539. #ifdef __STDC__
  540. void deinit (void)
  541. #else
  542.         public void
  543. deinit()
  544. #endif
  545. {
  546.         tputs(sc_deinit, sc_height, putchr);
  547. }
  548.  
  549. /*
  550.  * Home cursor (move to upper left corner of screen).
  551.  */
  552. #ifdef __STDC__
  553. void home (void)
  554. #else
  555.         public void
  556. home()
  557. #endif
  558. {
  559.         tputs(sc_home, 1, putchr);
  560. }
  561.  
  562. /*
  563.  * Add a blank line (called with cursor at home).
  564.  * Should scroll the display down.
  565.  */
  566. #ifdef __STDC__
  567. void add_line (void)
  568. #else
  569.         public void
  570. add_line()
  571. #endif
  572. {
  573.         tputs(sc_addline, sc_height, putchr);
  574. }
  575.  
  576. /*
  577.  * Move cursor to lower left corner of screen.
  578.  */
  579. #ifdef __STDC__
  580. void lower_left (void)
  581. #else
  582.         public void
  583. lower_left()
  584. #endif
  585. {
  586.         tputs(sc_lower_left, 1, putchr);
  587. }
  588.  
  589. /*
  590.  * Ring the terminal bell.
  591.  */
  592. #ifdef __STDC__
  593. void bell (void)
  594. #else
  595.         public void
  596. bell()
  597. #endif
  598. {
  599.         if (quiet == VERY_QUIET)
  600.                 vbell();
  601.         else
  602.                 putchr('\7');
  603. }
  604.  
  605. /*
  606.  * Output the "visual bell", if there is one.
  607.  */
  608. #ifdef __STDC__
  609. void vbell (void)
  610. #else
  611.         public void
  612. vbell()
  613. #endif
  614. {
  615.         if (*sc_visual_bell == '\0')
  616.                 return;
  617.         tputs(sc_visual_bell, sc_height, putchr);
  618. }
  619.  
  620. /*
  621.  * Clear the screen.
  622.  */
  623. #ifdef __STDC__
  624. void clear (void)
  625. #else
  626.         public void
  627. clear()
  628. #endif
  629. {
  630.         tputs(sc_clear, sc_height, putchr);
  631. }
  632.  
  633. /*
  634.  * Clear from the cursor to the end of the cursor's line.
  635.  * {{ This must not move the cursor. }}
  636.  */
  637. #ifdef __STDC__
  638. void clear_eol (void)
  639. #else
  640.         public void
  641. clear_eol()
  642. #endif
  643. {
  644.         tputs(sc_eol_clear, 1, putchr);
  645. }
  646.  
  647. /*
  648.  * Begin "standout" (bold, underline, or whatever).
  649.  */
  650. #ifdef __STDC__
  651. void so_enter (void)
  652. #else
  653.         public void
  654. so_enter()
  655. #endif
  656. {
  657.         tputs(sc_s_in, 1, putchr);
  658. }
  659.  
  660. /*
  661.  * End "standout".
  662.  */
  663. #ifdef __STDC__
  664. void so_exit (void)
  665. #else
  666.         public void
  667. so_exit()
  668. #endif
  669. {
  670.         tputs(sc_s_out, 1, putchr);
  671. }
  672.  
  673. /*
  674.  * Begin "underline" (hopefully real underlining,
  675.  * otherwise whatever the terminal provides).
  676.  */
  677. #ifdef __STDC__
  678. void ul_enter (void)
  679. #else
  680.         public void
  681. ul_enter()
  682. #endif
  683. {
  684.         tputs(sc_u_in, 1, putchr);
  685. }
  686.  
  687. /*
  688.  * End "underline".
  689.  */
  690. #ifdef __STDC__
  691. void ul_exit (void)
  692. #else
  693.         public void
  694. ul_exit()
  695. #endif
  696. {
  697.         tputs(sc_u_out, 1, putchr);
  698. }
  699.  
  700. /*
  701.  * Begin "bold"
  702.  */
  703. #ifdef __STDC__
  704. void bo_enter (void)
  705. #else
  706.         public void
  707. bo_enter()
  708. #endif
  709. {
  710.         tputs(sc_b_in, 1, putchr);
  711. }
  712.  
  713. /*
  714.  * End "bold".
  715.  */
  716. #ifdef __STDC__
  717. void bo_exit (void)
  718. #else
  719.         public void
  720. bo_exit()
  721. #endif
  722. {
  723.         tputs(sc_b_out, 1, putchr);
  724. }
  725.  
  726. #ifdef AMIGA
  727. /*
  728.  * Begin "italic" mode
  729.  */
  730. #ifdef __STDC__
  731. void it_enter (void)
  732. #else
  733.         public void
  734. it_enter()
  735. #endif
  736. {
  737.         tputs(sc_it_in, 1, putchr);
  738. }
  739.  
  740. /*
  741.  * End "italic"
  742.  */
  743. #ifdef __STDC__
  744. void it_exit (void)
  745. #else
  746.         public void
  747. it_exit()
  748. #endif
  749. {
  750.         tputs(sc_it_out, 1, putchr);
  751. }
  752.  
  753. /*
  754.  * Begin "inverse video"
  755.  */
  756. #ifdef __STDC__
  757. void nv_enter (void)
  758. #else
  759.         public void
  760. nv_enter()
  761. #endif
  762. {
  763.         tputs(sc_nv_in, 1, putchr);
  764. }
  765.  
  766. /*
  767.  * End "inverse video"
  768.  */
  769. #ifdef __STDC__
  770. void nv_exit (void)
  771. #else
  772.         public void
  773. nv_exit()
  774. #endif
  775. {
  776.         tputs(sc_nv_out, 1, putchr);
  777. }
  778. #endif
  779.  
  780. /*
  781.  * Erase the character to the left of the cursor
  782.  * and move the cursor left.
  783.  */
  784. #ifdef __STDC__
  785. void backspace (void)
  786. #else
  787.         public void
  788. backspace()
  789. #endif
  790. {
  791.         /*
  792.          * Try to erase the previous character by overstriking with a space.
  793.          */
  794.         tputs(sc_backspace, 1, putchr);
  795.         putchr(' ');
  796.         tputs(sc_backspace, 1, putchr);
  797. }
  798.  
  799. /*
  800.  * Output a plain backspace, without erasing the previous char.
  801.  */
  802. #ifdef __STDC__
  803. void putbs (void)
  804. #else
  805.         public void
  806. putbs()
  807. #endif
  808. {
  809.         tputs(sc_backspace, 1, putchr);
  810. }
  811.